using System;
using System.Diagnostics;
using System.IO;

namespace MindFactorial.LaunchPoint.Common
{
    /// <summary>
    /// Helper class to log errors to event log
    /// </summary>
    public abstract class Logger : LaunchPointObject
    {
        const int MAX_LOG_STRING_SIZE = 2000;
        const string FALLBACK_LOG_FILE = "error.log";
        const string EVENTLOG_SOURCE = "LaunchPointv3.0.11.0";
        static string _log_file_name, _root_directory;
        static Guid _file_guid;
        #region Public Methods

        static Logger()
        {
            _root_directory = "log";
            _file_guid = Guid.NewGuid();
            if (!Directory.Exists("log"))
                Directory.CreateDirectory("log");

            _log_file_name = string.Format("{0}/log_({1}).log", _root_directory, _file_guid);
        }

        


        /// <summary>
        /// write to log file, large Messages are truncated
        /// </summary>
        /// <param name="Message"></param>
        public static void Log(string Message)
        {
            try
            {
                if (Message.Length > MAX_LOG_STRING_SIZE)
                    Message = Message.Substring(0, MAX_LOG_STRING_SIZE);

                StreamWriter sw = File.AppendText(_log_file_name);
                sw.WriteLine(string.Format("[{0}] {1}", DateTime.Now, Message));
                sw.Close();
            }
            catch (Exception ex)
            {
                //TODO: exceptions here are essentially skipped
                //they may need to be logged to a file
                try
                {
                    _file_guid = Guid.NewGuid();
                    _log_file_name = string.Format("{0}/log_({1}).log", _root_directory, _file_guid);
                    StreamWriter sw = File.AppendText(_log_file_name);
                    sw.WriteLine(string.Format("[{0}] {1}",DateTime.Now,Message));
                    sw.Close();                               
                }
                catch (Exception ex2)
                {
                    //the Message goes unlogged   
                    string str = ex2.Message;                
                }            

            }
        }

      /// <summary>
      ///  write to event log, large Messages are truncated
      /// </summary>
      /// <param name="Message">Message to send</param>
      /// <param name="logEntryType">type of log entry</param>
        public static void Log(string Message, EventLogEntryType logEntryType)
        {
            try
            {
                if (Message.Length > MAX_LOG_STRING_SIZE)
                    Message = Message.Substring(0, MAX_LOG_STRING_SIZE);
                EventLog.WriteEntry(EVENTLOG_SOURCE, AppDomain.CurrentDomain.FriendlyName + ":" + Message, logEntryType);
            }
            catch (Exception ex)
            {
                //TODO: exceptions here are essentially skipped
                //they may need to be logged to a file
                try
                {
                    System.IO.File.AppendAllText(FALLBACK_LOG_FILE, "Could not write to log file because " + ex.Message + ", the original Message was " + Message);
                }
                catch (Exception ex2)
                {
                    string str = ex2.Message;
                    //the Message goes unlogged                                       
                }

            }
        }

        /// <summary>
        /// write to event log from formatted string
        /// </summary>
        /// <param name="format"></param>
        /// <param name="args"></param>
        public static void Log(string format, params string[] args)
        {
            Log( string.Format(format,args));           
        }


        /// <summary>
        /// write to event log from formatted string
        /// </summary>
        /// <param name="logEntryType"></param>
        /// <param name="format"></param>
        /// <param name="args"></param>
        public static void Log(EventLogEntryType logEntryType, string format, params string[] args)
        {
            Log(string.Format(format, args), logEntryType.ToString());
        }

        /// <summary>
        /// Log exception to windows event log.  By default this will 
        /// always be logged as EventLogEntryType.Error
        /// </summary>
        /// <param name="guid"></param>
        /// <param name="ex">exception to log</param>
        public static void Log(string guid, Exception ex)
        {
            Log("{0}: Message:{1} Trace:{1}",guid, ex.Message, ex.StackTrace);
        }      

        #endregion
    }
}
